package com.gitee.empty_null.pojo;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.gitee.empty_null.constants.DefaultConstants;
import com.gitee.empty_null.constants.ErrorCodes;
import com.gitee.empty_null.exception.domain.CodeDomain;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author xuhainan
 * @date 2024/1/15 15:55
 * @region hefei
 */
public class Result<T> implements Serializable {
    @Serial
    private static final long serialVersionUID = 7515042743397293535L;

    @JsonFormat(pattern = DefaultConstants.DATE_TIME_FORMAT)
    private final Date timestamp = new Date();
    private int code = 0;
    private String message;
    private String path;
    private T data;
    private String traceId;

    public Result() {
        super();
    }

    private static <T> Result<T> create(String message, int code, T data) {
        Result<T> result = new Result<>();
        if (StringUtils.isNotBlank(message)) {
            result.message(message);
        }
        result.code(code);
        if (ObjectUtils.isNotEmpty(data)) {
            result.data(data);
        }
        return result;
    }

    public static <T> Result<T> success(String message, int code, T data) {
        return create(message, code, data);
    }

    public static <T> Result<T> success(String message, T data) {
        return success(message, ErrorCodes.OK.getCode(), data);
    }

    public static <T> Result<T> success(String message) {
        return success(message, null);
    }

    public static <T> Result<T> success() {
        return success("操作成功！");
    }

    public static <T> Result<T> content(T data) {
        return success("操作成功！", data);
    }

    public static <T> Result<T> failure(String message, int code, T data) {
        return create(message, code, data);
    }

    public static <T> Result<T> failure(String message, T data) {
        return failure(message, ErrorCodes.INTERNAL_SERVER_ERROR.getCode(), data);
    }

    public static <T> Result<T> failure(CodeDomain codeDomain, T data) {
        return failure(codeDomain.getMessage(), codeDomain.getCode(), data);
    }

    public static <T> Result<T> failure(CodeDomain codeDomain) {
        return failure(codeDomain, null);
    }

    public static <T> Result<T> failure(String message) {
        return failure(message, null);
    }

    public static <T> Result<T> failure() {
        return failure("操作失败！");
    }

    public static <T> Result<T> empty(String message, int code) {
        return create(message, code, null);
    }

    public static <T> Result<T> empty(String message) {
        return empty(message, ErrorCodes.NO_CONTENT.getCode());
    }

    public static <T> Result<T> empty() {
        return empty("未查询到相关内容！");
    }

    public int getCode() {
        return code;
    }

    public String getMessage() {
        return message;
    }

    public String getPath() {
        return path;
    }

    public T getData() {
        return data;
    }


    public String getTraceId() {
        return traceId;
    }

    public Date getTimestamp() {
        return timestamp;
    }


    public Result<T> code(int code) {
        this.code = code;
        return this;
    }

    public Result<T> message(String message) {
        this.message = message;
        return this;
    }

    public Result<T> data(T data) {
        this.data = data;
        return this;
    }

    public Result<T> path(String path) {
        this.path = path;
        return this;
    }

    public Result<T> traceId(String traceId) {
        this.traceId = traceId;
        return this;
    }

    public Map<String, Object> toModel() {
        Map<String, Object> result = new HashMap<>(8);
        result.put("code", code);
        result.put("message", message);
        result.put("path", path);
        result.put("data", data);
        result.put("timestamp", timestamp);
        return result;
    }
}
